/*=+--+=#=+--     Unmanned Aerial System Management Software      --+=#=+--+=#*\
|          Copyright (C) 2011 Regents of the University of Colorado.           |
|                             All Rights Reserved.                             |

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as
     published by the Free Software Foundation.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

            Jack Elston                       Cory Dixon                        
|           elstonj@colorado.edu              dixonc@colorado.edu              |
|                                                                              |
\*=+--+=#=+--                 --+=#=+--+=#=+--                    --+=#=+--+=#*/

/***********************************************************************
 *			
 * FILENAME:
 * fileLog.h
 *
 * PURPOSE:
 * This code implements a simple log object to log data 
 * to a specific file type.
 *
 * CREATED:
 * 07/28/2002 by Cory Dixon
 *  
 * LAST MODIFIED:
 * $Author: dixonc $
 * $Date: 2005/07/13 21:00:06 $
 * $Revision: 1.4 $
 *
 ***********************************************************************/
#ifndef _LOG_H
#define _LOG_H

#ifndef __cplusplus
# error This library requires C++
#endif

#if defined( WIN32 ) 
#  include <windows.h>
#elif defined( VXWORKS )
# include "vxWorks.h"
#endif

#include <arpa/inet.h>

#include "timeLib.h"
#include "String.h"
#include "command.h"

#ifndef SVN_VER
#define SVN_VER "-1"
#endif

//  This class defines the structure of the log file.
//
class LogFileStruct 
{
	public:
		float32_t timeOfDay;
		in_addr   from;
		in_addr   to;
		uint16_t  numOfBytes;
		char    * bytes;

		LogFileStruct () {
			timeOfDay   = 0;
			numOfBytes  = 0;
			from.s_addr = INADDR_ANY;
			to.s_addr   = INADDR_ANY;
			bytes       = NULL;
		}

		~LogFileStruct () {
			if (bytes != NULL)
				delete [] bytes;
		}
};

//  Provides the log interface 
//
class FileLog {
	public:
		// Mode type
		typedef enum { READ, CREATE, APPEND, INCREMENT } FileLogMode;
#if defined( WIN32 )
		typedef HANDLE fd_type;
#else
		typedef int fd_type;
#endif

	private:
		fd_type     Fd;		 // log file descriptor
		String      fileName; // device name
		String      baseName; // base name
		bool        isOpened; // is opened flag

		size_t      bytesW;   // number bytes written to file
		size_t      fileS;    // size of file
		FileLogMode logMode;	// mode for logging
		TimeStamp   ts;
		struct tm   tmTime;   // time stamp in a tm struct
		int         svn_ver;  // svn version at time log file was created
		int         compiled_ver;  // svn version at time this was compiled

	public:
		// The base is the file name base, and every log file 
		// will end with a .log. The mode argment specifies
		// how to handle the log file name(s).
		// 
		// If the mode argument is INCREMENT, then the base file name 
		// will have a number appended to it based on the files present 
		// in the directory which is determined from the base String.  
		// For example, an auto-incrementing log name will generated as shown:
		// 	FileLog fl("/tffs0/log/socket", INCREMENT);
		// This will create files in the directory "/tffs0/log/"
		// named socket_1.log, socket_2.log, ... .
		// 
		// If mode argument is CREATE, then the file will simply
		// be created. If the log file already exsits, it will
		// be overwritten.
		//
		// If the mode argument is APPEND, then if the log file
		// already exsists the new logged data will be 
		// appended to the file, otherwise it is created and a new
		// log is started.
		//FileLog( const char* base = "tcLog", FileLogMode mode = APPEND);
		FileLog( String base = "tcLog", FileLogMode mode = APPEND);
		~FileLog();

		// get the file descriptor
		fd_type getFd(void) const			{ return Fd;  }
		// return file name
		String getFileName(void) const 	{ return fileName; }

		// open the log file for writing
		bool open();
		// open the log file for reading
		bool open(const String & name);
		bool isOpen() { return (Fd > 0); }

		// close the log file
		bool close();

		// These functions write data to the log file.
		// The returned value for the write functions, is not the
		// number of bytes written to the file, but the length of
		// bytes written from the buffer and should be equal to
		// buf_len.  If there is an error, the return value is ERROR.
		int write( int from, int to, const char * buf, uint16_t buf_len ); 
		int write( in_addr from, in_addr to, const char * buf, uint16_t buf_len ); 
		int write( int from, int to, const String& value);
		int write( int from, int to, const Command& cmd);

		// These functions read data from the log file.
		// It is the responsibility of the user to to parse
		// the returned bytes and format them.

		// read a line from the log file
		int read( LogFileStruct & line);
		// read n line(s) from the log file
		int read( LogFileStruct *line, size_t n);
		// get the time of the log file
		struct tm getTime () { return tmTime; }
		int getVersion() { return svn_ver; };


		// get bytes 
		size_t bytesWritten() const { return bytesW; }
		size_t fileSize() const { return (fileS + bytesW); }

};

#endif //_LOG_H

